package com.iisigroup.project.statistics;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;


public class FileScanModules {
    static private String rlFtlLocation="/opt/ramdisk/work/workspaces/eclipse_38/rl-config/RIS/share/FTL/";
    static protected String rlJspLocation="/opt/ramdisk/work/workspaces/eclipse_38/sris-rl-web/src/main/webapp/pages/func";
    static protected String rcJspLocation="/opt/ramdisk/work/workspaces/eclipse_38/RC/sris-rc-web/src/main/webapp/pages/func";
    static protected String rrJspLocation="/opt/ramdisk/work/workspaces/eclipse_38/RR/sris-rr-web/src/main/webapp/pages/func";
    static private Set<String> ftlSet ;
    
    public void setFtls(){
	if(ftlSet== null){
	    ftlSet =new HashSet<String>();	    
	}
	final File dir = new File(rlFtlLocation);
	String datacontent = StringUtils.join(dir.list() ,",");
	ftlSet.addAll( extractData(regexFTLCode, datacontent));
    }
    final static  String regexFTLCode = "[a-zA-Z0-9]{4}\\d{6}";
    final static  String regexJspInclude = "<ui:include[\\s]*src[\\s]*=[\\s]*['|\"].*.xhtml['|\"][\\s]*/>";
    final static  String regexJspInclude2 = "[\\s]*url[\\s]*=[\\s]*['|\"].*.xhtml[a-zA-Z0-9_/?.=#{}]*['|\"]"; 
    final static  String regexJspIncludePage = "[a-zA-Z0-9_/.#{}]*.xhtml";
    
    final static String regxCd="../";
    /**
     * @param args
     */
    public static void main(String[] args)throws IOException {
	FileScanModules ss = new FileScanModules();
	Map<String, List<File>> map = ss.arrayByFunName(rlJspLocation);
	System.out.println(map.size());
	
	// RlConstant.NOTE_CODE_2003000001
	String  sampleLine = "        String hNoteCode = RlConstant.NOTE_CODE_GA03000001;       ";
	Set<String> init = extractData(regexFTLCode, sampleLine);
	System.out.println(init.size());
	for(String line : init){
	    System.out.println(line);
	}
	
	 //../../misc/rl03100/rl03100Caller_js.xhtml
	String path = "../../misc/rl03100/rl03100Caller_js.xhtml";
	String samplePath = "			var url = \"#{application.contextPath}/faces/pages/misc/rl03100/rl03100_result.xhtml?windowId=#{currentWindow.id}\";";
	
	int count = StringUtils.countMatches(path ,regxCd); 
	System.out.println(count);
	String regularEx ="#(.+?).xhtml";
	Set<String> dataSet = extractData(regularEx, samplePath);
	System.out.println(dataSet.size());
	
	//#{application.contextPath}/faces/pages/misc/rl03100/rl03100_result.xhtml
	String sampleString1="<p:inputText readonly=\"true\" styleClass=\"readonly-input\" value=\"#{rl0a420Controller.dto.registerDate}\">";
	String sampleString2="var url = \"#{application.contextPath}/faces/pages/misc/rl03100/rl03100_result.xhtml\";";
	String testER="[\\s]*url[\\s]*=[\\s]*['|\"].*.xhtml[a-zA-Z0-9_/?.=#{}]*['|\"]"; 
	Set<String> dataSet1 = extractData(testER, sampleString2);
	System.out.println(dataSet1); 
		// '#{request.contextPath}/faces/pages/func/rl05292/rl05292_detail.xhtml
				//#{application.contextPath}/faces/pages/misc/rl03100/rl03100_result.xhtml
	String sample  = "#{application.contextPath}/faces/pages/misc/rl03100/rl03100_result.xhtml";
	String sampleExtr = "[#][{][a-zA-Z0-9.]*[}]";
	String sampleExtrExist = "[#][{][a-zA-Z0-9.]*[}]/faces.*";
	 String controllerXxr="[a-zA-Z0-9.]*Controller";
	 
	 dataSet = extractData(sampleExtr, sample);
	 
	System.out.println();
    }
    public  Set<String> extractRSCDFromjspFiles(final List<File> fileList){
	Set<String> result =new HashSet<String>();
	for(final File unitFile : fileList){
	    try {
		String fileContent = FileUtils.readFileToString(unitFile);
		Set<String> dataSet = extractData(regexRSCD, fileContent);
		result.addAll(dataSet);
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}
	
	return result;
    }
    //<ui:include src="../../../func/rl0a420/rl0a420.xhtml" />
    public  Set<String> extractControllerNameFormFiles(final List<File> fileList){
	String sampleExtr = "[#][{][a-zA-Z0-9.]*[}]";
	String controllerXxr="[a-zA-Z0-9.]*Controller";
	Set<String> result =new HashSet<String>();
	for(final File unitFile : fileList){
	    try {
		String fileContent = FileUtils.readFileToString(unitFile);
		Set<String> dataSet = extractData(sampleExtr, fileContent);
		for(String unitContent : dataSet){
		    Set<String> unc = extractData(controllerXxr, unitContent);
		    result.addAll(unc);
		}
	    } catch (IOException e) {
		e.printStackTrace();
	    }
	}
	
	return result;
    } 
    protected  static  File extractFileFromString(final String raw ,  final String pageRootPath,final File jspFile){
	File result = null;
	final String sampleExtr = "[#][{][a-zA-Z0-9.]*[}]/faces";
	final String sampleExtrExist = "[#][{][a-zA-Z0-9.]*[}]/faces.*";
	    Set<String> jspLinkCollection = extractData(FileScanModules.regexJspIncludePage, raw);
	    String pageInfo = StringUtils.EMPTY;
	    if (CollectionUtils.isNotEmpty(jspLinkCollection)) {
		while (jspLinkCollection.iterator().hasNext()) {
		    pageInfo = jspLinkCollection.iterator().next();
		    break;
		}
	    }
	    final Matcher matcher = Pattern.compile(sampleExtrExist).matcher(pageInfo);
	    
	    String filePath = StringUtils.EMPTY;
	    if (matcher.matches()) {
		// '#{request.contextPath}/faces/pages/func/rl05292/rl05292_detail.xhtml
		//#{application.contextPath}/faces/pages/misc/rl03100/rl03100_result.xhtml		
		filePath = Pattern.compile(sampleExtr).matcher(pageInfo).replaceFirst(pageRootPath);;
	    } else if (StringUtils.contains(pageInfo, "../")) {
		// ../../misc/rl03100/rl03100Caller_js.xhtml
		int count = StringUtils.countMatches(pageInfo, regxCd);
		final File folder = jspFile.getParentFile();
		File fsearchFolder = folder;
		for (int i = 0; i < count; ++i) {
		    fsearchFolder = fsearchFolder.getParentFile();
		}
		filePath = fsearchFolder.getAbsolutePath() + File.separator + StringUtils.remove(pageInfo, "../").replace("'", "");

	    }
	    if (StringUtils.isNotBlank(filePath)) {
		File file = new File(filePath);
		if (file.exists()) {
		    result = file;
		}
	    }
	return result;
    }
    /***
     * 根據jspFile 頁面資訊找尋被include的頁面
     * @param jspFile
     * *****/
    public static File  getFileFromParsingFile(final File jspFile,final String pageRootPath ) throws IOException{
//	final String pageRootPath = "/opt/ramdisk/work/workspaces/eclipse_38/sris-rl-web/src/main/webapp";
//	if(jspFile.getName().equals("rl03100Caller_js.xhtml")){
//	    System.out.println("rl03100Caller_js.xhtml");
//	}
	// '#{request.contextPath}/faces/pages/func/rl05292/rl05292_detail.xhtml
	// /opt/ramdisk/work/workspaces/eclipse_38/sris-rl-web/src/main/webapp/pages/func/rl05292/rl05292_detail.xhtml
	File result = null;
	final String fileContent = FileUtils.readFileToString(jspFile);
	Set<String> initData = extractData(regexJspInclude, fileContent);
	for (String raw : initData) {
	    result =extractFileFromString(raw, pageRootPath,  jspFile);
	}
	if(result==null && CollectionUtils.isEmpty(initData)){
	    Set<String> init2Data = extractData(regexJspInclude2, fileContent);
	    //url = "#{application.contextPath}/faces/pages/misc/rl03100/rl03100_result.xhtml?windowId=#{currentWindow.id}"
	  
	    for (String raw : init2Data) {
		result = extractFileFromString(raw, pageRootPath,  jspFile);
		if (result != null) {
		    break;
		}
	    }
	}
	
	return result;
    }
    public Map<String ,List<File>>  arrayByFunName(String rootPath)  {
	final File root = new File(rootPath);
	
	final Map<String ,List<File>> funJspMap = new HashMap<String, List<File>>();
	final 	Collection<File> listAllFiles = getAllFiles(root); 
	for(final File jsp :listAllFiles){
	    final  String folderName = jsp.getParentFile().getName(); 
	    final String funcName =StringUtils.upperCase( StringUtils.remove(folderName,"_"));
	    List<File> list = funJspMap.get(funcName);
	    if(list  ==  null){
		list = new ArrayList<File>();
	    }
	    list.add(jsp);
	    funJspMap.put(funcName, list);
	}
	return funJspMap ; 
    }
    public List<File> getAllFiles( final File root  ) {

	List<File> allFiles = new ArrayList<File>();
	Queue<File> dirs = new LinkedList<File>();
	dirs.add(root);
	while (!dirs.isEmpty()) {
	  for (File f : dirs.poll().listFiles()) {
	    if (f.isDirectory()) {
	      dirs.add(f);
	    } else if (f.isFile()) {
	      allFiles.add(f);
	    }
	  }
	}
	return allFiles;
    }
    
    final String regexRSCD = "RSCD\\d{4}";
   
    protected static Set<String>  extractData(final String expr ,final String src){
	 final Set<String> init=new HashSet<String>();
	
	 final Pattern pattern = Pattern.compile(expr);
	 final Matcher matcher = pattern.matcher(src);
	 while(matcher.find()){	    
	     String extraData = matcher.group();
	     init.add(extraData);
	 }
	 return init;
    }
    public  Set<String> extractRSCDsFromSrc(final String root ,final Class<?> clazz){
	String fileContent = StringUtils.EMPTY;
	try {
	    final String filePath = root + File.separator +StringUtils.replace(clazz.getCanonicalName(), ".",File.separator)+".java";
	    final  File realFile = new File(filePath) ;
	    //inner Interface ,或是 inner Class用此方法會造成內容路徑不正確
	    if(realFile.exists()){
		fileContent = FileUtils.readFileToString(realFile);
	    }	    
	} catch (IOException e) {
	    e.printStackTrace();
	}
	Set<String> init = extractData(regexRSCD, fileContent);
	return init;
    }
    public  List<String> extractFtlsFromJavaSrc(final String root ,final Class<?> clazz){
	
	String fileContent = StringUtils.EMPTY;
	try {
	    final String filePath = root + File.separator +StringUtils.replace(clazz.getCanonicalName(), ".",File.separator)+".java";
	    final  File realFile = new File(filePath) ;
	    
	    //inner Interface ,或是 inner Class用此方法會造成內容路徑不正確
	    if(realFile.exists()){
		 fileContent = FileUtils.readFileToString(realFile);		
	    }
	} catch (IOException e) {
	    e.printStackTrace();
	}
	Set<String> init = extractData(regexFTLCode, fileContent);
	
	final List<String>  result =new ArrayList<String>();
	for(String unit : init){
	    if(ftlSet.contains(unit)){
		result.add(unit);
	    }
	}
	 Collections.sort(result);
	
	return result;
    }
}
